<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!-->  <html class="no-js" lang="en"> <!--<![endif]-->
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	
	<title>Iterator</title>
	
	<meta name="description" content="A jQuery library for modern HTML presentations">
	<meta name="author" content="Caleb Troughton">
	<meta name="viewport" content="width=1024, user-scalable=no">
	
	<!-- Core and extension CSS files -->
	<link rel="stylesheet" href="../core/deck.core.css">
	<link rel="stylesheet" href="../extensions/goto/deck.goto.css">
	<link rel="stylesheet" href="../extensions/menu/deck.menu.css">
	<link rel="stylesheet" href="../extensions/navigation/deck.navigation.css">
	<link rel="stylesheet" href="../extensions/status/deck.status.css">
	<link rel="stylesheet" href="../extensions/hash/deck.hash.css">
	<link rel="stylesheet" href="../extensions/scale/deck.scale.css">
	
	<!-- Style theme. More available in /themes/style/ or create your own. -->
	<link rel="stylesheet" href="../themes/style/swiss.css">
	
	<!-- Transition theme. More available in /themes/transition/ or create your own. -->
	<link rel="stylesheet" href="../themes/transition/horizontal-slide.css">
	
	<script src="../modernizr.custom.js"></script>
	

    <!-- SintaxHighlighter -->
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>SyntaxHighlighter Large File Demo</title>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/XRegExp.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shCore.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushJava.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushPlain.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushPython.js"></script>
	<link type="text/css" rel="stylesheet" href="../SyntaxHighlighter-master/styles/shCoreEclipse.css"/>
	<!--link type="text/css" rel="stylesheet" href="../SyntaxHighlighter-master/styles/shThemeEclipse.css"/-->
	
	<script type="text/javascript">SyntaxHighlighter.all();</script>

	
	
</head>

<body class="deck-container">

<!-- Begin slides -->
<section class="slide" id="iterator1">
	<h2>Iterator</h2>
	<p>Hay muchas maneras de guardar cosas en una colección, podemos guardar en Stacks, Array, ArrayList, HashTable, cada una tiene sus ventajas y desventajas, pero en algún punto hay que iterar los objetos, y cuando lo hacemos es bueno no mostrarle la implemnetacion al cliente.</p>
	<p>Vamos a juntar 2 implementaciones de restaurant. Uno hace panqueques y el otro desayunos, y tienen la misma implementacion para los item de menú pero usan distintas colecciones, uno usa ArrayList y el otro Array</p>
</section>
<section class="slide" id="iterator2">
	<h2>Iterator</h2>
	<h4>Veamos una de las implementaciones de los menu</h4>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class PancakeHouseMenu implements Menu {
			ArrayList menuItems;
			public PancakeHouseMenu() {
				menuItems = new ArrayList();
		    
				addItem("K&B's Pancake Breakfast", 
					"Pancakes with scrambled eggs, and toast", true, 2.99);
				addItem("Regular Pancake Breakfast", 
					"Pancakes with fried eggs, sausage", false, 2.99);
				addItem("Blueberry Pancakes",
					"Pancakes made with fresh blueberries", true, 3.49);
				addItem("Waffles",
					"Waffles, with your choice of blueberries or strawberries", true, 3.59);
			}
			public void addItem(String name, String description,
			                    boolean vegetarian, double price)
			{
				MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
				menuItems.add(menuItem);
			}
			public ArrayList getMenuItems() {
				return menuItems;
			}
			// other menu methods here
		}
	</script>
</section>
<section class="slide" id="iterator3">
	<h2>Iterator</h2>
	<ul>
		<li>Esta la implementación que usa ArrayList</li>
		<li>Cada item de menú se agrega en el constructor llamando al método addItem()</li>
		<li>addItem() crea un nuevo menuitem, y lo agrega al ArrayList</li>
		<li><p>getMenuItems() retorna el ArrayList con los items.</p>
			<p>Acá le estamos mostrando la implementación al cliente porque le pasamos el ArrayList.<p/>
			<p>Si cambiamos el tipo de colección todos los que usan este método tienen que cambiar sus implementaciones.</p>
		</li>
	</ul>
</section>
<section class="slide" id="iterator4">
	<h2>Iterator</h2>
	<h4>Veamos la otra implementacion de los menu</h4>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class DinerMenu implements Menu {
			static final int MAX_ITEMS = 6;
			int numberOfItems = 0;
			MenuItem[] menuItems;
		  
			public DinerMenu() {
				menuItems = new MenuItem[MAX_ITEMS];
		 
				addItem("Vegetarian BLT",
					"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
				addItem("BLT",
					"Bacon with lettuce & tomato on whole wheat", false, 2.99);
				addItem("Soup of the day",
					"Soup of the day, with a side of potato salad", false, 3.29);
				addItem("Hotdog",
					"A hot dog, with saurkraut, relish, onions, topped with cheese",
					false, 3.05);
				addItem("Steamed Veggies and Brown Rice",
					"Steamed vegetables over brown rice", true, 3.99);
				addItem("Pasta",
					"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
					true, 3.89);
			}
		  
			public void addItem(String name, String description, 
			                     boolean vegetarian, double price) 
			{
				MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
				if (numberOfItems >= MAX_ITEMS) {
					System.err.println("Sorry, menu is full!  Can't add item to menu");
				} else {
					menuItems[numberOfItems] = menuItem;
					numberOfItems = numberOfItems + 1;
				}
			}
			public MenuItem[] getMenuItems() {
				return menuItems;
			}
			// other menu methods here
		}
	</script>
</section>
<section class="slide" id="iterator5">
	<h2>Iterator</h2>
	<ul>
		<li>Esta la implementación que usa Array en vez de ArrayList</li>
		<li>addItem() crea un nuevo menuitem, y lo agrega al Array pero esta ves tiene que controlar cual es la posición libre, ademas de no pasarse del tamaño</li>
		<li><p>getMenuItems() retorna el Array con los items.</p>
			<p>Al igual que en PancakeHouseMenu los clientes de este método tiene que cambiar las implementaciones en el caso de un cambio de colección</p> 
		</li>
	</ul>
</section>
<section class="slide" id="iterator6">
	<h2>Iterator</h2>
	<h4>Tenemos que hacer un cliente que use los dos menus. Vamos a implementar los siguientes métodos</h4>
	<p>Implementemos printMenu(), que imprime todos los items del menu</p>
	<ul>
		<li>Para imprimir todos los los items tenemos que llamar al método getMenuItem() en las clases DinerMenu y PancakeHouseMenu y obtener las colecciones
			<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
				PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
				ArrayList breakfastItems = pancakeHouseMenu.getMenuItems();

				DinerMenu dinerMenu = new DinerMenu();
				MenuItem[] lunchItems = dinerMenu.getMenuItems();
			</script>
		</li>
		<li>Luego iteramos para imprimir los items del ArrayList y luego para los del Array
		<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
			for (int i = 0; i < breakfastItems.size(); i++) {
				MenuItem menuItem = breakfastItems.get(i);
				System.out.print(menuItem.getName());
				System.out.println("\t\t" + menuItem.getPrice());
				System.out.println("\t" + menuItem.getDescription());
			}
			
			for (int i = 0; i < lunchItems.length; i++) {
				MenuItem menuItem = lunchItems[i];
				System.out.print(menuItem.getName());
				System.out.println("\t\t" + menuItem.getPrice());
				System.out.println("\t" + menuItem.getDescription());
			}
		</script>
		</li>
	</ul>
	<p>Esto nos va a pasar para cada uno de los métodos que tenga que leer los items de los Menús</p>
</section>
<section class="slide" id="iterator7">
	<h2>Iterator</h2>
	<p>Sería bueno encontrar una interface que permitiera implementar la misma interface a los menús.
		Si no fuera por la diferencia del tipo que devuelve getMenuItem(), de esta manera podríamos minimizar las referencias concretas y evitar las iteraciones múltiples
	</p>
	<p>El patrón Itrator nos va a ayudar a encapsular iteración.</p>
	<img src="arrayListIterator.png"/></li>
</section>
<section class="slide" id="iterator6c">
	<h2>Iterator</h2>
	<img src="arrayIterator.png"/>
	<p>Con iterator el cliente obtiene un iterator en ves de la colección y con este puede acceder a los elementos de una forma única</p>
</section>
<section class="slide" id="iterator7">
	<h2>Iterator</h2>
	<p>El patrón Iterator depende de una interfaz llamada Iterator</p>
	<p>Para agregar un iterador a DinerMenu primero definimos la interfaz iterator</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public interface Iterator {
			boolean hasNext();
			Object next();
		}
	</script>
	<p>Como estamos usando java vamos a usar la intefaz <strong>java.util.iterator</strong>, en vez de usar la definida por nosotros.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public interface Iterator<E> {
			boolean hasNext();
			E next();
			void remove();
		}
	</script>	
</section>
<section class="slide" id="iterator7b">
	<h2>Iterator</h2>
	<p>Y ahora necesitamos implementar el iterador concreto para DinerMenu</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		import java.util.Iterator;
		public class DinerMenuIterator implements Iterator {
			MenuItem[] items;
			int position = 0; //posicion actual
			public DinerMenuIterator(MenuItem[] items) {
				//recibe en el contructor el Array
				this.items = items;
			}
			public Object next() {
				MenuItem menuItem = items[position];
				position = position + 1;
				return menuItem;
			}
			public boolean hasNext() {
				if (position >= items.length || items[position] == null) {	
					return false;
				} else {
					return true;
				}
			}
			public void remove() {
				if (position <= 0) {
					throw new IllegalStateException
						("You can't remove an item until you've done at least one next()");
				}
				if (list[position-1] != null) {
					for (int i = position-1; i < (list.length-1); i++) {
						list[i] = list[i+1];
					}
					list[list.length-1] = null;
				}
			}
		}
	</script>
	<p>Cuando hasNext() devuelve false, quiere decir se acabaron las posiciones o la siguiente posición  es null. Cuando esto se da, tengo que terminar con las iteraciones</p>
</section>
<section class="slide" id="iterator8">
	<h2>Iterator</h2>
	<h4>Retocamos DinerMenu para usar DinerMenuIterator</h4>
	<p>Le vamos a agregar el método create iterator y vamos a sacar el método getMenuItems() ya que no lo vamos a usar mas y expone la implementación interna</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public Iterator createIterator() {
			return new DinerMenuIterator(menuItems);
		}
	</script>
	<p>El método createIterator() devuelve un objeto DinerMenuIterator usando el Array y se lo devuelve al cliente</p>
	<p>El cliente va a recibir un iterator y no tiene porque saber como esta implementado el iterator. Lo único que tiene que saber es como se usa un iterator, e ir recorriendo los elementos.</p></bR>
	<p>Para la clase PancakeHouseMenu tenemos que implementar tambien el metodo createIterator(), pero como usa ArrayList que ya tiene Iterator implementado, así que simplemente lo devolvemos</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public Iterator createIterator() {
			return menuItems.iterator();
		}
	</script>
</section>
<section class="slide" id="iterator9">
	<h2>Iterator</h2>
	<h4>Retocamos el cliente.</h4> 
	<p>El método printMenu() era uno de los que iteraba las colecciones que le devolvian las clases PancakeHouseMenu y DinerMenu cuando invocabamos el método getMenuItems(). Este era el que tenía los dos bucles.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		import java.util.Iterator;
		public class Waitress {
			PancakeHouseMenu pancakeHouseMenu;
			DinerMenu dinerMenu;
		 
			public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
				this.pancakeHouseMenu = pancakeHouseMenu;
				this.dinerMenu = dinerMenu;
			}
		 
			public void printMenu() {
				Iterator pancakeIterator = pancakeHouseMenu.createIterator();
				Iterator dinerIterator = dinerMenu.createIterator();

				System.out.println("MENU\n----\nBREAKFAST");
				printMenu(pancakeIterator);
				System.out.println("\nLUNCH");
				printMenu(dinerIterator);
			}
		 
			private void printMenu(Iterator iterator) {
				while (iterator.hasNext()) {
					MenuItem menuItem = (MenuItem)iterator.next();
					System.out.print(menuItem.getName() + ", ");
					System.out.print(menuItem.getPrice() + " -- ");
					System.out.println(menuItem.getDescription());
				}
			}
		 	//other methods here
		}
	</script>
	<p>Ahora el método <strong>printMenu(Iterator iterator)</strong> que recibe un Iterator imprime sin saber que implementacion interna tiene la coleccion. En esta implementacion usamos el mismo método para iterar los elementos de los dos menús,  PancakeHouseMenu y DinerMenu</p>
</section>
<section class="slide" id="iterator10">
	<h2>Iterator</h2>
	<h4>Mejoras en el diseño</h4> 
	<ul>
		<li>Ahora la implementacion del menu esta encapsulada. Antes cuando queríamos los items del menú obteníamos un ArrayList o un Array con lo que no se respetaba la encapsulación.</li>
		<li>Iteramos colecciones que polimorficamente soportan cualquier coleccion que implemente la interfaz java.util.Iterator.</li>
		<li>Lo otro que logramos es que los menus tengan exactamente los mismos métodos.</li>
	</ul>
	<p>Lo que nos falta es que implementen una iterfaz común.</p>
</section>
<section class="slide" id="iterator11">
	<h2>Iterator</h2>
	<h4>Implementamos una iterfaz común</h4> 
	<p>Lo que nos falta es que implementen una iterfaz común en para los menús.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public interface Menu {
			public Iterator createIterator();
		}
	</script>
	<p>Hacemos que <strong>PancakeHouseMenu</strong> y <strong>DinerMenu</strong> implementen Menu en las definiciones de clase</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class PancakeHouseMenu implements Menu {}
		public class DinerMenu implements Menu {}
	</script>
	<p>y cambiamos el código de Waitress para que no referencia a las implementaciones concretas sino a la interfaz</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	 	public class Waitress {
	  		PancakeHouseMenu pancakeHouseMenu;
	    	DinerMenu dinerMenu;
	  
	 		public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
	    	    this.pancakeHouseMenu = pancakeHouseMenu;
	        	this.dinerMenu = dinerMenu;
	    	}
	    // rest of the code
	    }	
	</script>
	<p>Por este que referencia la interface Menu</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		import java.util.Iterator;
		public class Waitress {
			Menu pancakeHouseMenu;
			Menu dinerMenu;
		 
			public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
				this.pancakeHouseMenu = pancakeHouseMenu;
				this.dinerMenu = dinerMenu;
			}
		// rest of the code	
	    }
	</script>
</section>
<section class="slide" id="iterator12">
	<h2>Iterator</h2>
	<h4>Como quedo el diseño</h4> 
	<ul>
		<li>PancakeHouseMenu y DinerMenu implementan la interface Menú.</li>
		<li>Waitress refiere a los menú usando la interface <strong>Menu</strong> en ves de una clase concreta. Esto reduce la dependencia enter Waitress y las clases concretas. Recordemos <strong>"Programar a interfaces no a implementaciones"</strong></li>
		<li>Desacoplamos a Waitress de las implementaciones de los menús, y podemos iterar sobre cualquier lista de items sin saber la implementación.
		<li>Estructura:</li>
	</ul>	
	<img src="restaurantClassDiagram.png"/>
</section>

<section class="slide" id="iterator13">
	<h2>Patron Iterator</h2>
	<p>Proporcionar acceso secuencial a los elementos de un agregado, sin exponer su representación interna.</p>
	<ul>
		<li>Motivación:
			<ul>
				<li>Una lista debe proporcionar un medio de navegar por sus datos sin exponer su estructura interna</li>
				<li>Se debe poder atravesar la lista de varias maneras, pero no añadir operaciones a la lista por cada tipo de recorrido</li>
				<li>Se debe poder realizar varios recorridos simultáneamente</li>
				<li>La solución que propone el patrón es dar la responsabilidad del recorrido a un objeto iterador.</li>
				</ul>
			</ul>
		</li>
		<li>Aplicabilidad: 
			<ul>
				<li>Cuando se quiere acceder al contenido de un agregado sin exponer su representación interna</li>
				<li>Cuando se quieren permitir varios recorridos sobre un agregado</li>
				<li>Para proporcionar una interfaz uniforme para recorrer distintos tipos de agregados (esto es, permitir iteración polimórfica)</li>
			</ul>	
		</li>
	</ul>	
</section>
<section class="slide" id="iterator14">
	<h2>Patron Iterator</h2>
	<ul>
		<li>Participantes: 
		<ul>
			<li><strong>Iterator:</strong> define interfaz para acceder y recorrer elementos</li>
			<li><strong>ConcreteIterator:</strong>
				<ul>
					<li>Implementa la interfaz Iterator</li>
					<li>Mantiene la posición actual en el recorrido del agregado</li>
				</ul>
			</li>
			<li><strong>Aggregate:</strong> define interfaz para crear un objeto Iterator</li>
			<li><strong>ConcreteAggregate:</strong> implementa una interfaz de creación del Iterator para devolver la instancia de ConcreteIterator apropiada</li>
		</ul>	
		</li>
		<li>Consecuencias: Permite variaciones en el recorrido de un agregado
			<ul>
				<li>Para cambiar el algoritmo de recorrido basta cambiar la instancia de Iterator concreta</li>
				<li>Nuevos recorridos mediante nuevas subclases de Iterator</li>
			</ul>
		</li>
		<li>Los iteradores simplifican la interfaz del agregado</li>
		<li>Puede hacerse más de un recorrido a la vez sobre un mismo agregado</li>
	</ul>	
</section>
<section class="slide" id="iterator15">
	<h2>Patron Iterator</h2>
	<ul>
		<li>Estructura: 
			<img src="IteratorClassDiagram.png"/>
		</li>
	</ul>	
</section>
<section class="slide" id="iterator16">
	<h2>Iterator en java</h2>
	<ul>
		<li><strong>Iterator:</strong>interfaz java.util.Iterator</li>
		<li><strong>ConcreteIterator:</strong>implementaciones concretas de Iterator</li>
		<li><strong>Aggregate:</strong>Las interfaces Collection, Set, SortedSet, List, Queue de java.util. Incluyen el método iterator(), que devuelve un iterador genérico</li>
		<li><strong>ConcreteAggregate:</strong> implementaciones de esas interfaces.<BR/>
			Set es implementada por las clases HashTree, TreeSet, LinkedHashSet.<BR/>
			List es implementada por las clases ArrayList, LinkedList.
		</li>
	</ul>
	<img src="javaCollectionsClassDiagram.png"/>
</section>
<section class="slide" id="iterator17">
	<h2>Principio de diseño</h2>
	<h3>Única responsabilidad</h3>
	<h4>Una clase debe tener solo una razón para cambiar</h4>
	<p>Qué tiene de malo si nuestro agregados implementan sus colecciones y operaciones relacionadas?</p>
	<p>Cuando se toman mas responsabilidades (como la iteración) le estamos dando a la clase 2 razones para cambiar
		<ul>
			<li>Si la colección cambia tiene que cambiar</li>
			<li>Si queremos cambiar la forma de iterar</li>
		</ul>
	</p>
	<p>Sabemos que siempre tratamos de evitar el cambio a toda costa, porque sabemos todas las oportunidades de generar problemas que esto tiene. Tener 2 razones para cambiar incrementa las posibilidades de cambio.</p>
	<p>La solución es asignar solo una responsabilidad a una clase. Si bien esto no es una tarea fácil, hay observar cuando una clase esta cambiando en mas de una manera.</p>
</section>
<section class="slide" id="iterator18">
	<h2>Iterator</h2>
	<p>Si bien el diseño quedo bastante bien, cada vez que queremos agregar un menu nuevo tenemos que tocar el código de la clase Waitress, para agregar la referencia al menú</p>
	<p>Estamos violando el principio de <strong>"Las clases tiene que estar abiertas para la extensión pero cerradas para la modificación."</strong></p>
	<p>Ponemos los menús y luego iteramos cada menú</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Waitress {
			ArrayList menus;
			public Waitress(ArrayList menus) {
				this.menus = menus;
			}
			public void printMenu() {
				Iterator menuIterator = menus.iterator();
				while(menuIterator.hasNext()) {
					Menu menu = (Menu)menuIterator.next();
					printMenu(menu.createIterator());
				}
			}
			//Iteramos la coleccion menus y pasamos el iterador
			//de cada menu a printMenu(Iterator iterator)

			void printMenu(Iterator iterator) {
				while (iterator.hasNext()) {
					MenuItem menuItem = (MenuItem)iterator.next();
					System.out.print(menuItem.getName() + ", ");
					System.out.print(menuItem.getPrice() + " -- ");
					System.out.println(menuItem.getDescription());
				}
			}
		}  
	</script>
	<p>Como perdimos los nombres de los menús, le agregamos nombres a cada menú</p>
	</script>
</section>
<section class="slide" id="iterator19">
	<h2>Iterator</h2>
	<h4>Ahora si queremos agregar un submenu postre</h4>
	<p>Tendríamos no solo que soportar múltiple menús, sino que menús submenús</p>
	<p>Seria deseable que el menú dessert sea un elemento de la colección DinnerMenu</p>
	<img src="subMenu.png"/>
	<p>Necesitamos guardar un subMenu en DinerMenu, pero no podemos Asignar un Menu a un Array de MenuItem porque son tipos diferentes.</p>
</section>
<section class="slide" id="iterator20">
	<h2>Iterator</h2>
	<h4>Refactoring</h4>
	<p>Con el nivel de complejidad que alcanzamos si no hacemos un refactoring no vamos a poder soportar la funcionalidad de submenus.</p>
	<ul>
		<li>Necesitamos una estructura de árbol para guardar los menús y submenus
			<img src="treeMenuStructure.png"/>
		</li>
	</ul>	
</section>
<section class="slide" id="iterator21">
	<h2>Iterator</h2>
	<h4>Refactoring</h4>
	<ul>
		<li>Necesitamso asegurarnos que hay una manera de recorrer los item de cada menú
			<img src="treeMenuStructureTransverse.png"/>
		</li>
		<li>Podríamos necesitar recorrer los items de una manera mas flexible que la actual, como por ejemplo recorrer todos los items de los postres o el menu de la Cena inclusive con los postres
			<img src="treeMenuStructureTransverseSubMenu.png"/>	
		</li>
	</ul>	
</section>
<section class="slide" id="iterator22">
	<h2>Patrón Compostite</h2>
	<p>Componer objetos en estructuras arbóreas para representar jerarquías todo-parte. Manipular todos los objetos del árbol de manera uniforme</p>
	<ul>
		<li>Motivación: Poniendo objetos simples (menuItems) y contenedores (menús) en la misma estructura creamos una estructura de todo-parte que los clientes los tratan de la misma manera.
		</li>
		<li>Aplicabilidad: 
			<ul>
				<li>Cuando queremos representar jerarquías de objetos todo-parte</li>
				<li>Cuando queremos ser capaz de ignorar la diferencia entre objetos individuales y composiciones de objetos. Los clientes tratarán a todos los objetos de la estructura compuesta uniformemente.</li>
			</ul>	
		</li>
	</ul>
</section>
<section class="slide" id="iterator23">
	<h2>Patrón Compostite</h2>
	<ul>
		<li>Participantes: 
		<ul>
			<li><strong>Component:</strong>
				<ul>
					<li>define la interfaz común para los objetos de la composición</li>
					<li>define la interfaz para acceder y gestionar los hijos</li>
					<li>puede definir un comportamiento por defecto común a las subclases</li>
					<li>(opcional) define la interfaz para acceder al padre de un componente en la estructura recursiva, y la implementa si es apropiado</li>
				</ul>
			</li>
			<li><strong>Leaf:</strong>
				<ul>
					<li>representa los objetos hoja (sin hijos) de la composición</li>
					<li>define comportamiento para los objetos primitivos</li>
				</ul>
			</li>
			<li><strong>Composite:</strong>
				<ul>
					<li>define comportamiento para los componentes que tienen hijos</li>
					<li>almacena componentes hijo</li>
					<li>implementa las operaciones de Component para la gestión de hijos</li>
				</ul>
			</li>
			<li><strong>Client:</strong> manipula los objetos de la composición a través de la interfaz Component</li>
		</ul>	
		</li>
	</ul>	
</section>
</section>
<section class="slide" id="iterator24">
	<h2>Patrón Compostite</h2>
	<ul>
		<li>Consecuencias:
			<ul>
				<li>Define jerarquías de clases hechas de objetos primitivos y compuestos. Si el código cliente espera un objeto simple, puede recibir también uno compuesto</li>
				<li>Simplifica el cliente. Objetos simples y compuestos se tratan homogéneamente</li>
				<li>Facilita la incorporación de nuevos tipos de componentes</li>
				<li>Puede hacer el diseño demasiado general. Es complicado restringir el tipo de componentes de un composite.</li>
			</ul>
		</li>
		<li>Los iteradores simplifican la interfaz del agregado</li>
		<li>Puede hacerse más de un recorrido a la vez sobre un mismo agregado</li>
	</ul>	
</section>

<section class="slide" id="iterator25">
	<h2>Patrón Compostite</h2>
	<ul>
		<li>Estructura: 
			<img src="compositeClassDiagram.png"/>
		</li>
	</ul>	
</section>
<section class="slide" id="iterator26">
	<h2>Compostite</h2>
	<h4>Aplicando Composite a los menus</h4>
	<p>Creamos una interface común que va a ser interface de Menus y MenuItems y nos permite tratarlos de manera uniforme. Osea van a tener los mismo mentodos los Menu y MenuItems</p>
	<img src="CompositeRestarurantClassDiagram.png"/>
</section>
<section class="slide" id="iterator27">
	<h2>Compostite</h2>
	<h4>Aplicando Composite a los menus</h4>
	<ul>
		<li>Waitress: va a usar MenuComponet como interface de acceso a Menu y MenuItems</li>
		<li>MenuComponent: la interface de Menu y MenuItem. En la implemnetacion usamos una clase abstracta para poder proveer implmenteciones por default. Tenemos una combianciones de los métodos de las implementaciones anteriores de Menu y MenuItem, y ademas agregamos print(), add(), remove(), getChild()</li>
		<li>MenuItem: sobreescribe los que le interesan y los deja los que no (add(), remove(), etc), ya que solo podemos agregar componentes al Menú.
		</li>
		<li>Menu: sobreescribe los métodos que necesita y los que no deja la implementacion por defecto.</li>
	</ul>
</section>
<section class="slide" id="iterator28">
	<h2>Compostite</h2>
	<h4>Implmentamos MenuComponent</h4>
	<p>Esta es la clase <strong>Component</strong> en el diagra Composite</p>
	<p>Parecería que MenuComponent tiene 2 funciones y por eso la implementacion por defecto no va a hacer nada, así que los hijos van a a tener una única función relacionado con los métodos que sobre escriban.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public abstract class MenuComponent {
		//estos son los metodos que usa MenuComponent
		public void add(MenuComponent menuComponent) {
			throw new UnsupportedOperationException();
		}
		public void remove(MenuComponent menuComponent) {
			throw new UnsupportedOperationException();
		}
		public MenuComponent getChild(int i) {
			throw new UnsupportedOperationException();
		}
	  
	  	//estos son los métodos usados tanto por MenuComponent como por Menu
		public String getName() {
			throw new UnsupportedOperationException();
		}
		public String getDescription() {
			throw new UnsupportedOperationException();
		}
		public double getPrice() {
			throw new UnsupportedOperationException();
		}
		public boolean isVegetarian() {
			throw new UnsupportedOperationException();
		}
	  
		public void print() {
			throw new UnsupportedOperationException();
		}
	}
	</script>
</section>
<section class="slide" id="iterator29">
	<h2>Compostite</h2>
	<h4>Implementamos MenuItem</h4>
	<p>Esta es una de las clases <strong>leaf</strong> en el diagra Composite, implementa el comportamiento de elementos en el composite</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class MenuItem extends MenuComponent {
			String name;
			String description;
			boolean vegetarian;
			double price;
		    
			public MenuItem(String name, String description, 
			                boolean vegetarian, double price) 
			{ 
				this.name = name;
				this.description = description;
				this.vegetarian = vegetarian;
				this.price = price;
			}
			public String getName() {
				return name;
			}
			public String getDescription() {
				return description;
			}
			public double getPrice() {
				return price;
			}
			public boolean isVegetarian() {
				return vegetarian;
			}
			public void print() {
				System.out.print("  " + getName());
				if (isVegetarian()) {
					System.out.print("(v)");
				}
				System.out.println(", " + getPrice());
				System.out.println("     -- " + getDescription());
			}
		}
	</script>
	<ul>
		<li>Extiende de MenuComponent</li>
		<li>implementamos los getName(), getDescription(), getPrice(), isVegetarian() para que no tiren exepcion y print() para que imprima todos los datos del item.</li>
	</ul>	
</section>
<section class="slide" id="iterator30">
	<h2>Compostite</h2>
	<h4>Implementamos Menu</h4>
	<p>Esta es la clase <strong>composite</strong> que puede guardar MenuItems o Menus</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Menu extends MenuComponent {
			ArrayList menuComponents = new ArrayList();
			String name;
			String description;
		  
			public Menu(String name, String description) {
				this.name = name;
				this.description = description;
			}
			public void add(MenuComponent menuComponent) {
				menuComponents.add(menuComponent);
			}
			public void remove(MenuComponent menuComponent) {
				menuComponents.remove(menuComponent);
			}
			public MenuComponent getChild(int i) {
				return (MenuComponent)menuComponents.get(i);
			}
			public String getName() {
				return name;
			}
			public String getDescription() {
				return description;
			}
			public void print() {
				System.out.print("\n" + getName());
				System.out.println(", " + getDescription());
				System.out.println("---------------------");
		  
				Iterator iterator = menuComponents.iterator();
				while (iterator.hasNext()) {
					MenuComponent menuComponent =  (MenuComponent)iterator.next();
					menuComponent.print();
				}
			}
		}
	</script>
	<ul>
		<li>Usamos un ArrayList para guardar los MenuItems o Menús</li>
		<li>Guardamos en nombre para saber que menú es, esto era distinto cuando teníamos distintas atributos para cada menu.</li>
		<li>add(), remove() y getChild() funcionan tanto para Menú como para MenuItems ya que ambos son menuComent</li>
		<li>print() itera en todos los elementos de la colección y a cada uno (Menu o MenuItem) le delega la impresión ya que ambos cuentan con la implementación. De esta manera se van a ir llamando recursivamente a los MenuComponente hasta que uno sea una hoja osea un MenuItem y e imprima y ahí se corta la llamada recursiva.</li>
	</ul>	
</section>
<section class="slide" id="iterator31">
	<h2>Compostite</h2>
	<h4>Implementamos Waitress</h4>
	<p>Esta era la clase que <strong>cliente</strong></p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Waitress {
			MenuComponent allMenus;
			public Waitress(MenuComponent allMenus) {
				this.allMenus = allMenus;
			}
			public void printMenu() {
				allMenus.print();
			}
		}
	</script>
</section>
<section class="slide" id="iterator31b">
	<h2>Compostite</h2>
	<h4>Testeamso el composite</h4>
	<p>En esta clase creamos los Menu y MenuItem y armamos el árbol</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class MenuTestDrive {
			public static void main(String args[]) {
				//creo los primeros Menus
				MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast");
				MenuComponent dinerMenu = new Menu("DINER MENU", "Lunch");
				MenuComponent cafeMenu = new Menu("CAFE MENU", "Dinner");
				MenuComponent dessertMenu = new Menu("DESSERT MENU", "Dessert of course!");
		  
				MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
				//agrego Menus al elementos Menu que contine el resto
				allMenus.add(pancakeHouseMenu);
				allMenus.add(dinerMenu);
				allMenus.add(cafeMenu);
				
				//agrego items al pancakeHouseMenu
				pancakeHouseMenu.add(new MenuItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99));
				pancakeHouseMenu.add(new MenuItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 	2.99));
				pancakeHouseMenu.add(new MenuItem("Blueberry Pancakes", "Pancakes made with fresh blueberries, and blueberry syrup", true, 3.49));
				pancakeHouseMenu.add(new MenuItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59));

				//agrego items al dimerMenu	
				dinerMenu.add(new MenuItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99));
				dinerMenu.add(new MenuItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99));
				dinerMenu.add(new MenuItem("Soup of the day", "A bowl of the soup of the day, with a side of potato salad", false, 3.29));
				
				//aca le estoy agregando un Menu al dinerMenu
				dinerMenu.add(dessertMenu);
				
				//agrego items al desertMenu
				dessertMenu.add(new MenuItem("Apple Pie","Apple pie with a flakey crust, topped with vanilla icecream", true, 1.59));
				dessertMenu.add(new MenuItem("Cheesecake", "Creamy New York cheesecake, with a chocolate graham crust", true, 1.99));
				
				//rest of the code
				Waitress waitress = new Waitress(allMenus);
		  
				waitress.printMenu();
			}
		}
	</script>
</section>
<section class="slide" id="iterator32">
	<h2>Compostite</h2>
	<h4>Estructura de menus y submenus</h4>
	<p>Todos los elementos del árbol son <strong>MenuComponent</strong> pero las hojas son <strong>Menu</strong> y los que tienen "hijos" son <strong>MenuItem</strong></p>
	<img src="dinerTree.png"/>
</section>
<section class="slide" id="iterator33">
	<h2>Compostite</h2>
	<h4>Composite Iterator</h4>
	<p>Ya estamos usando Iterator en la implementacion interna print() de los Menus, pero si queremos que la mesera (waitress) itere el composite entero por ejemplo si quiere recorrer todo y sacar los items vegetarianos, tenemos que cambiar la implementación.</p>
	<p>Para implementar el Composite Iterator vamos a agregar createIterator() en cada component</p>
	<p>Arrancamos con la clase abstracta MenuComponet</p>
	<p>Esto significa que cada Menú y MenuItem van a tener que implementar este método.<BR/>
	Esto significa también que llamando a createIterator() en el composite debería aplicar a todos los hijos del composite.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Menu extends MenuComponent {	
			//other code here doesn't change
			public Iterator createIterator() {
				return new CompositeIterator(menuComponents.iterator());
			}
		}	
	</script>
	<p>Vamos usar el CompositeIterator, que sabe como iterar sobre un composite. Recibe como parámetro el iterator del menú</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class MenuItem extends MenuComponent {
			//other code here doesn't change
			public Iterator createIterator() {
				return new NullIterator();
			}
		}	
	</script>
	<p>Los MenuItems no tienen tienen items para iterar, devuelve un null iterator</p>
	<p>Siempre retorna false cuando invocamos hasNext()
		El código es el siguiente
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	import java.util.Iterator;
		public class NullIterator implements Iterator {
			public Object next() {
				return null;
			}
			public boolean hasNext() {
				return false;
			}
			public void remove() {
				throw new UnsupportedOperationException();
			}
		}
	</script>
	</p>
</section>


<section class="slide" id="iterator34">
	<h2>Compostite</h2>
	<h4>Composite Iterator</h4>
	<p>El composite iterator tiene que iterar sobre los menuItems y asegurarse de que los Menu hijos, junto con sus hijos que tambien puede ser alguno Menu y así hasta que no queden mas menu hijos y se hayan iterados todos las menuItems (hojas) de todos los Menus</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class CompositeIterator implements Iterator {
			Stack stack = new Stack();
		   	
			public CompositeIterator(Iterator iterator) {
				stack.push(iterator);
			}
		   
			public Object next() {
				if (hasNext()) {
					Iterator iterator = (Iterator) stack.peek();
					//devuelve el objeto de mas arriba de la pila sin eliminarlo
					MenuComponent component = (MenuComponent) iterator.next();
					if (component instanceof Menu) {
						stack.push(component.createIterator());
					} 
					return component;
				} else {
					return null;
				}
			}
		  
			public boolean hasNext() {
				if (stack.empty()) {
					return false;
				} else {
					Iterator iterator = (Iterator) stack.peek();
					if (!iterator.hasNext()) {
						stack.pop();
						return hasNext();
					} else {
						return true;
					}
				}
			}
		  
			public void remove() {
				throw new UnsupportedOperationException();
			}
			//no vamos a remover elementos asi que tiramos exception
		}
	</script>
</section>
<section class="slide" id="iterator35">
	<h2>Compostite</h2>
	<h4>Composite Iterator</h4>

	<ul>
		<li>Como todo iterador implementa la interfaz java.util.iterator</li>
		<li>
			<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
				public CompositeIterator(Iterator iterator) {
					stack.push(iterator);
				}
			</script>
			En el contructor le pasamos el iterador del nivel mas alto del composite que vamos a recorrer. Lo ponemos en un estructura de pila (stack)</li>
		<li>
			<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
				public Object next() {
					if (hasNext()) {
						Iterator iterator = (Iterator) stack.peek();
						//Si hay proximo elemento, tomamos el iterador de la pila
						MenuComponent component = (MenuComponent) iterator.next();
						//del iterador devuelto tomamos el proximo elemento
						if (component instanceof Menu) {
							//Si el elemento que nos devuelve el iterador es un Menu, 
							//tenemos otro composite que necesitamos 
							//incluir en la iteración asi que lo ponemos en la pila
							stack.push(component.createIterator());
						} 
						return component;
					} 
					else {
						return null;
					}
				}
			</script>	
		</li>
		<li>
			<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
				public boolean hasNext() {
					if (stack.empty()) {
						//miramos si la pila esta vacia
						return false;
					} 
					else {
						Iterator iterator = (Iterator) stack.peek();
						//si no esta vacia tomamos el iterador 
						if (!iterator.hasNext()) {
							//si no tiene mas elementos
							//lo eliminamos de la pila
							stack.pop();
							return hasNext();
							//llamamos a la funcion recursivamente
						} 
						else {
							return true;
						}
					}
				}
			</script>
		</li>
	</ul>
</section>
<section class="slide" id="iterator35">
	<h2>Compostite</h2>
	<h4>Composite Iterator</h4>
	<p>Cuando implementamos el print() en la clase MenuComponet usamos un iterador para recorrer los nodos en el componente si el nodo era un Menu en ves de un MenuItem entonces llamábamos recursivamente al método print(). MenuComponent manejaba la iteracion internamente.</p>
	<p>Con este código estamos implementando un iterador externo que debe mantener su posicion en la iteracion para que el cliente externo pueda menejar la interacion llamando a next() y hasNext(). Pero en este caso necesitamos la posición sobre la estructura recursiva del composite.</p>
	<p>La pila es la que mantiene nuestra posiciona mientras vamos para arriba y para abajo en la estructura de árbol del composite</p>
</section>
<section class="slide" id="iterator35">
	<h2>Compostite</h2>
	<h4>Usemos el Composite Iterator</h4>
	<p>Ya tenemos la manera de iterar desde el cliente todos los elementos del menú (MenuItems y Menú). Así que busquemos un menú vegetariano.</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Waitress {
			MenuComponent allMenus;
			public Waitress(MenuComponent allMenus) {
				this.allMenus = allMenus;
			}
			public void printMenu() {
				allMenus.print();
			}
			public void printVegetarianMenu() {
				Iterator iterator = allMenus.createIterator();
				System.out.println("\nVEGETARIAN MENU\n----");
				while (iterator.hasNext()) {
					MenuComponent menuComponent = 
							(MenuComponent)iterator.next();
					try {
						if (menuComponent.isVegetarian()) {
							menuComponent.print();
						}
					} catch (UnsupportedOperationException e) {}
				}
			}
		}
	</script>
	<p>Cacheamos la excepción porque en la clase abstract MenuComponent implmentamos isVegetarian() que tirar excepción y como en los Menú no esta implementado porque no soporta la operacion, nos va a tirar excepción. Por eso la cacheamos y seguimos recorriendo </p>
</section>

<section class="slide" id="iterator188">
	<h2>Referencias</h2>
	<p><strong>Head First Design Patterns</strong></p>
	<a href="http://www.ntu.edu.sg/home/ehchua/programming/java/J5c_Collection.html">JAVA Collection Framework</a>
</section>

<!----------------------------------------------------------------------------------------------->
<!-- deck.navigation snippet -->
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>

<!-- deck.status snippet -->
<p class="deck-status">
	<span class="deck-status-current"></span>
	/
	<span class="deck-status-total"></span>
</p>

<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
	<label for="goto-slide">Go to slide:</label>
	<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
	<datalist id="goto-datalist"></datalist>
	<input type="submit" value="Go">
</form>

<!-- deck.hash snippet -->
<a href="." title="Permalink to this slide" class="deck-permalink">#</a>


<!-- Grab CDN jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../jquery-1.7.2.min.js"><\/script>')</script>

<!-- Deck Core and extensions -->
<script src="../core/deck.core.js"></script>
<script src="../extensions/hash/deck.hash.js"></script>
<script src="../extensions/menu/deck.menu.js"></script>
<script src="../extensions/goto/deck.goto.js"></script>
<script src="../extensions/status/deck.status.js"></script>
<script src="../extensions/navigation/deck.navigation.js"></script>
<script src="../extensions/scale/deck.scale.js"></script>

<!-- Initialize the deck -->
<script>
$(function() {
	$.deck('.slide');
});
</script>

</body>



</html>
